package jp.ac.u_tokyo.dch.service;

import java.util.List;

import jp.ac.u_tokyo.dch.core.db.DBConnection;
import jp.ac.u_tokyo.dch.core.exceptions.DBException;
import jp.ac.u_tokyo.dch.dao.common.FieldMasterDao;
import jp.ac.u_tokyo.dch.dao.common.SeqenceGenerator;
import jp.ac.u_tokyo.dch.dao.schema.DataSchemaDao;
import jp.ac.u_tokyo.dch.dao.schema.DataSchemaDetailDao;
import jp.ac.u_tokyo.dch.dao.schema.TypeItemsDao;
import jp.ac.u_tokyo.dch.model.db.DataSchema;
import jp.ac.u_tokyo.dch.model.db.DataSchemaDetail;
import jp.ac.u_tokyo.dch.util.common.CommonUtil;
import jp.ac.u_tokyo.dch.view.Constants;
import jp.ac.u_tokyo.dch.view.outputschema.SchemaView;

/**
 *
 * @version 1.1
 *
 */
public class DataSchemaService {

	/**
	* DBコネクションオブジェクト
	 */
	private DBConnection dbconn = null;


	/**
	 * オブジェクト生成者
	 * @param dbconn
	 */
	public DataSchemaService(DBConnection dbconn){
		this.dbconn = dbconn;
	}

	/**
	 * データスキーマリストを取得する
	 * @param sort 分類
	 * @return データスキーマリスト
	 * @throws DBException 例外
	 */
	public List<DataSchema> getList(String sort) throws DBException {

		DataSchemaDao schemaDao = new DataSchemaDao(dbconn);

		return schemaDao.selectList(sort);
	}

	/**
	 * データスキーマを取得する
	 * @param schemaid データスキーマID
	 * @return データスキーマ
	 * @throws DBException 例外
	 */
	public DataSchema findSchema(String schemaid) throws DBException {

		DataSchemaDao schemaDao = new DataSchemaDao(dbconn);

		return schemaDao.selectObject(schemaid);
	}

	/**
	 *
	 * @param schemaid
	 * @param customSign
	 * @return
	 * @throws DBException
	 */
	public List<DataSchemaDetail> getSchemaDetailList(String schemaid, String customSign) throws DBException {

		DataSchemaDetailDao schemaDetailDao = new DataSchemaDetailDao(dbconn);
		TypeItemsDao typeItemsDao = new TypeItemsDao(dbconn);
		FieldMasterDao fieldMasterDao = new FieldMasterDao(dbconn);

		List<DataSchemaDetail> schemaDetailList = schemaDetailDao.selectList(schemaid, customSign);
		setOptionItems(typeItemsDao, fieldMasterDao, schemaDetailList);

		return schemaDetailList;
	}


	/**
	 * 画面モデルにセットする
	 * @param view 画面モデル
	 * @param schemaid スキーマID
	 * @throws DBException 例外
	 */
	public void setOutputSchemaView(SchemaView view, String schemaid) throws DBException {

		DataSchemaDao schemaDao = new DataSchemaDao(dbconn);
		DataSchemaDetailDao schemaDetailDao = new DataSchemaDetailDao(dbconn);
		TypeItemsDao typeItemsDao = new TypeItemsDao(dbconn);
		FieldMasterDao fieldMasterDao = new FieldMasterDao(dbconn);

		DataSchema dataSchema = schemaDao.selectObject(schemaid);
		List<DataSchemaDetail> schemaItemList = schemaDetailDao.selectList(schemaid, "0");
		List<DataSchemaDetail> customItemList = schemaDetailDao.selectList(schemaid, "1");


		view.setDataSchema(dataSchema);
		view.setSchemaItemList(schemaItemList);
		view.setCustomItemList(customItemList);

		setOptionItems(typeItemsDao, fieldMasterDao, schemaItemList);
		setOptionItems(typeItemsDao, fieldMasterDao, customItemList);

	}

	/**
	 * 挿入する
	 * @param view 画面モデル
	 * @throws DBException 例外
	 */
	public void insert(SchemaView view) throws DBException {

		DataSchemaDao schemaDao = new DataSchemaDao(dbconn);
		DataSchemaDetailDao schemaDetailDao = new DataSchemaDetailDao(dbconn);
		TypeItemsDao typeItemsDao = new TypeItemsDao(dbconn);
		FieldMasterDao fieldMasterDao = new FieldMasterDao(dbconn);
		SeqenceGenerator seqenceGenerator = new SeqenceGenerator(dbconn);

		int seq = seqenceGenerator.getSequence(SeqenceGenerator.DATA_SCHEMA_SEQ);

		List<DataSchemaDetail> schemaItemList = view.getSchemaItemList();
		List<DataSchemaDetail> customItemList = view.getCustomItemList();

		insertOptions(seq, schemaItemList, typeItemsDao);
		insertOptions(seq, customItemList, typeItemsDao);

		schemaDetailDao.insertAll(schemaItemList, seq);
		schemaDetailDao.insertAll(customItemList, seq);

		fieldMasterDao.insertAll(customItemList);

		DataSchema schema = view.getDataSchema();

		schema.setSchemaid(String.valueOf(seq));

		schemaDao.insert(schema);
	}

	/**
	 * 更新する
	 * @param view 画面モデル
	 * @throws DBException 例外
	 */
	public void update(SchemaView view) throws DBException {

		DataSchemaDao schemaDao = new DataSchemaDao(dbconn);
		DataSchemaDetailDao schemaDetailDao = new DataSchemaDetailDao(dbconn);
		TypeItemsDao typeItemsDao = new TypeItemsDao(dbconn);
		FieldMasterDao fieldMasterDao = new FieldMasterDao(dbconn);

		DataSchema schema = view.getDataSchema();

		int schemaid = Integer.valueOf(schema.getSchemaid());

		List<DataSchemaDetail> schemaItemList = view.getSchemaItemList();
		List<DataSchemaDetail> customItemList = view.getCustomItemList();

		//カスタムデータ削除
		fieldMasterDao.deleteCustom(schemaid);
		schemaDetailDao.deleteCustom(schemaid);
		typeItemsDao.delete(schemaid);

		schemaDetailDao.updateAll(schemaItemList);
		schemaDetailDao.insertAll(customItemList, schemaid);
		fieldMasterDao.insertAll(customItemList);

		insertOptions(schemaid, schemaItemList, typeItemsDao);
		insertOptions(schemaid, customItemList, typeItemsDao);

		schemaDao.update(schema);

	}

	/**
	 *
	 * @param view 画面モデル
	 * @throws DBException 例外
	 */
	public void delete(SchemaView view) throws DBException {

		DataSchemaDao schemaDao = new DataSchemaDao(dbconn);
		DataSchemaDetailDao schemaDetailDao = new DataSchemaDetailDao(dbconn);
		TypeItemsDao typeItemsDao = new TypeItemsDao(dbconn);
		FieldMasterDao fieldMasterDao = new FieldMasterDao(dbconn);

		DataSchema schema = view.getDataSchema();

		int schemaid = Integer.valueOf(schema.getSchemaid());

		fieldMasterDao.deleteCustom(schemaid);
		schemaDao.delete(schemaid);
		schemaDetailDao.deleteAll(schemaid);
		typeItemsDao.delete(schemaid);

	}

	/**
	 * データ名をチェックする
	 * @param name データ名
	 * @param schemaId スキーマID
	 * @return true:重複する名前がある、false:なし
	 * @throws DBException 例外
	 */
	public boolean checkName(String sort,String name, String schemaId) throws DBException {

		DataSchemaDao schemaDao = new DataSchemaDao(dbconn);

		return schemaDao.checkSchemaName(sort, name, schemaId);
	}

	/**
	 * オプションアイテムをセット
	 * @param typeItemsDao アイテムDAO
	 * @param itemList アイテムリスト
	 * @throws DBException 例外
	 */
	private void setOptionItems(TypeItemsDao typeItemsDao, FieldMasterDao fieldMasterDao, List<DataSchemaDetail> itemList) throws DBException {

		for (DataSchemaDetail detail : itemList) {

			String inputType = detail.getInputType();
			String optionKbn = detail.getOptionKbn();
			//オプションある場合
			if (CommonUtil.hasOptionInputType(inputType, optionKbn)) {

				String options = typeItemsDao.selectOptions(Integer.valueOf(detail.getSchemaid()), detail.getFieldKey());
				detail.setOptions(options);

				if (Constants.INPUT_TYPE_FIELDSELECT.equals(inputType)) {

					detail.setFieldDisplayname(fieldMasterDao.selectObject(options).getDisplayName());

				}
			}
		}
	}

	/**
	 * オプションを挿入する
	 * @param schemaId スキーマID
	 * @param itemList アイテムリスト
	 * @param typeItemsDao アイテムDAO
	 * @throws DBException 例外
	 */
	private void insertOptions(int schemaId, List<DataSchemaDetail> itemList, TypeItemsDao typeItemsDao) throws DBException {

		for (DataSchemaDetail detail : itemList) {

			String inputType = detail.getInputType();
			String optionKbn = detail.getOptionKbn();
			//オプションある場合
			if (CommonUtil.hasOptionInputType(inputType, optionKbn)) {

				typeItemsDao.insert(schemaId, detail.getOptions(), detail.getFieldKey());
			}
		}

	}

}
